package com.example.demo;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.BeetlTemplateEngine;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.example.demo.core.base.BizEntity;
import com.example.demo.core.base.BizMapper;
import com.example.demo.core.base.BizService;
import com.example.demo.core.base.BizServiceImpl;

import java.util.*;

public class CodeGenerator {
    /**
     * <p>
     * 读取控制台内容
     * </p>
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入" + tip + "：");
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotBlank(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "！");
    }

    public static void main(String[] args) {
        // 作者
        String author = "JXY";
        String outputDir = "/flow-server-study/src/main";
        String dataName = "marketing";
        // 要生成代码的表
        String[] tables = {
                "canvas_actuator",
                "canvas_event",
                "canvas_event_type",
                "canvas_info",
                "canvas_node",
                "canvas_node_relation",
                "canvas_node_statistics",
                "canvas_trigger",
                "canvas_user",
                "email_sender_info",
                "merchant_info",
                "reach_info",
                "reach_record",
                "reach_template",
                "user_group",
                "user_group_property",
                "user_group_user"
        };
        generator(author, outputDir, dataName, tables);
    }

    public static void generator(String author, String outputDir, String dataName, String[] tables) {
        // 获取当前系统目录
        String projectPath = System.getProperty("user.dir");

        // 1. 全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig
                .setEntityName("%sEntity")
                .setActiveRecord(true) // 是否支持AR模式
                .setAuthor(author)
                .setOutputDir(projectPath + outputDir + "/java")
                .setOpen(false)// 生成后是否打开资源管理器
                .setFileOverride(false) // 文件覆盖
                .setIdType(IdType.AUTO) // 主键策略
                .setEnableCache(false)
                .setServiceName("%sService") // 设置生成的service接口的名字的首字母是否为I 去掉
                .setBaseResultMap(true)// 生成基本的resultMap
                .setBaseColumnList(true)// 生成基本的SQL片段
//                .setSwagger2(true)// 开启Swagger2
        ;


        // 2. 数据源配置
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig
                .setDbType(DbType.MYSQL) // 设置数据库类型
                .setDriverName("com.mysql.cj.jdbc.Driver")
                .setUrl("jdbc:mysql://127.0.0.1:3306/"+ dataName +"?useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai")
                .setUsername("root")
                .setPassword("123456");



        // 3. 包名策略配置
        PackageConfig packageConfig = new PackageConfig();
        packageConfig
                .setParent("com.example.demo")
                .setController("controller")
                .setEntity("entity.entity")
                .setService("service")
                .setMapper("mapper")
                .setModuleName("mp")
        ;

        // 4. 策略配置globalConfiguration中
        StrategyConfig strategy = new StrategyConfig();
        strategy
                .setInclude(tables)// 指定扫描的表的名称,多张表之间以英文逗号分隔
                .setColumnNaming(NamingStrategy.underline_to_camel)// 数据库表字段映射到实体的命名策略
                .setNaming(NamingStrategy.underline_to_camel) // 数据库表映射到实体的命名策略
                .setEntityLombokModel(true) // Lombok 模型@Accessors(chain = true) setter 链式操作
                .setRestControllerStyle(true) // @RestController
                .setEntityTableFieldAnnotationEnable(true)// 字段注解
                .setSuperEntityClass(BizEntity.class)
//                .setSuperEntityClass("com.example.demo.core.base.BizEntity")
//                .setSuperEntityColumns("id","created_time","updated_time","deleted")
                .setSuperEntityColumns("id", "merchant_id", "create_time", "update_time", "deleted")
                .setSuperServiceClass(BizService.class)
//                .setSuperServiceClass("com.example.demo.core.base.BizService")
                .setSuperServiceImplClass(BizServiceImpl.class)
                .setSuperMapperClass("com.example.demo.core.base.BizMapper")
//                .setControllerMappingHyphenStyle(true)// url中驼峰转连字符 mpCanvas -> mp-canvas
//                .setLogicDeleteFieldName("deleted")// 逻辑删除字段设置
//                .setTablePrefix(packageConfig.getModuleName() + "_")//去掉表前缀 指定扫描表的前缀

        ;


        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
//                HashMap<String, Object> map = new HashMap<String, Object>();
//                map.put("superColums", this.getConfig().getStrategyConfig().getSuperEntityColumns());
//                this.setMap(map);
            }
        };
        // 如果模板引擎是 freemarker
        String templatePath = "/templates/mapper.xml.ftl";
        // 如果模板引擎是 velocity
//        String templatePath = "/templates/mapper.xml.vm";// FIXME
        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定义配置会被优先输出
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
                return projectPath
                        + outputDir + "/resources/mapper/"
//                        + packageConfig.getModuleName() + "/"
                        + tableInfo.getEntityName() + "Mapper"
                        + StringPool.DOT_XML;
            }
        });
        cfg.setFileOutConfigList(focList);


        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();
//        templateConfig.disable(TemplateType.CONTROLLER);
//        templateConfig.disable(TemplateType.XML);
        templateConfig.setXml(null);// FIXME 猜测 设置不使用模板

        // 代码生成器
        AutoGenerator autoGenerator = new AutoGenerator();

        autoGenerator
                .setGlobalConfig(globalConfig)
                .setDataSource(dataSourceConfig)
                .setStrategy(strategy)
                .setPackageInfo(packageConfig)
                .setCfg(cfg)
                .setTemplate(templateConfig)
                .setTemplateEngine(new FreemarkerTemplateEngine())// FIXME 会报错 使用 "/templates/mapper.xml.ftl" 就可以

// set beetl engine
//        .setTemplateEngine(new BeetlTemplateEngine())

// set custom engine (reference class is your custom engine class)
//        .setTemplateEngine(new CustomTemplateEngine())
        ;
        // 6. 执行
        autoGenerator.execute();
    }
}

